import json

import jenkins
from flask import request, current_app
from sqlalchemy import desc

from apps.extention.models.cijob import CiJob
from library.api.db import db
from library.api.transfer import transfer2json


class CiJobBusiness(object):

    @classmethod
    def _query(cls):
        return CiJob.query.add_columns(
            CiJob.id.label('id'),
            CiJob.number.label('number'),
            CiJob.url.label('url'),
            CiJob.ci_id.label('ci_id'),
            CiJob.start_name.label('start_name'),
            CiJob.status.label('status'),
            CiJob.report.label('report'),
            CiJob.run_date.label('run_date'),
            CiJob.run_time.label('run_time'),
            CiJob.job_count.label('job_count'),
            CiJob.job_accuracy.label('job_accuracy'),
        )

    @classmethod
    @transfer2json(
        '?id|!number|!url|!ci_id|!start_name|!status|!report|!run_date|!run_time|!job_count|!job_accuracy')
    def query_all_json(cls):
        return cls._query().filter(CiJob.status == CiJob.ACTIVE).order_by(desc(CiJob.id)).all()

    @classmethod
    @transfer2json(
        '?id|!number|!url|!ci_id|!start_name|!status|!report|!run_date|!run_time|!job_count|!job_accuracy')
    def query_number_all(cls, ciid):
        return cls._query().filter(CiJob.status == CiJob.ACTIVE, CiJob.ci_id == ciid).all()

    @classmethod
    @transfer2json(
        '?id|!number|!url|!ci_id|!start_name|!status|!report|!run_date|!run_time|!job_count|!job_accuracy')
    def query_number_id(cls, number, ciid):
        return cls._query().filter(CiJob.status == CiJob.ACTIVE, CiJob.number == number, CiJob.ci_id == ciid).all()

    @classmethod
    @transfer2json(
        '?id|!number|!url|!ci_id|!start_name|!status|!report|!run_date|!run_time|!job_count|!job_accuracy')
    def query_json_by_id(cls, id, page_size, page_index):

        start_time = request.args.get('start_time')
        end_time = request.args.get('end_time')
        start_name = request.args.get('start_name')
        return cls._query().filter(CiJob.ci_id == id,
                                   CiJob.status == CiJob.ACTIVE, CiJob.run_date.between(start_time, end_time),
                                   CiJob.start_name.like('%{}%'.format(start_name))).order_by(desc(CiJob.id)).limit(
            int(page_size)).offset(
            int(page_index - 1) * int(page_size)).all()

    @classmethod
    def query_count(cls, id):
        start_time = request.args.get('start_time')
        end_time = request.args.get('end_time')
        start_name = request.args.get('start_name')
        return CiJob.query.filter(CiJob.ci_id == id, CiJob.status == CiJob.ACTIVE,
                                  CiJob.run_date.between(start_time, end_time),
                                  CiJob.start_name.like('%{}%'.format(start_name))).count()

    @classmethod
    def create(cls, number, url, ci_id, start_name, report, run_date, run_time, job_count, job_accuracy):
        try:
            ci_job = CiJob(
                number=number,
                url=url,
                ci_id=ci_id,
                start_name=start_name,
                report=report,
                run_date=run_date,
                run_time=run_time,
                job_count=job_count,
                job_accuracy=job_accuracy,
            )
            db.session.add(ci_job)
            db.session.commit()
            return 0, None
        except Exception as e:
            current_app.logger.error(str(e))
            return 102, str(e)

    @classmethod
    def update(cls, id, number, url, ci_id, start_name, report, run_date, run_time, job_count, job_accuracy):
        try:
            cijob = CiJob.query.get(id)
            cijob.number = number
            cijob.url = url
            cijob.ci_id = ci_id
            cijob.start_name = start_name
            cijob.report = report
            cijob.run_date = run_date
            cijob.run_time = run_time
            cijob.job_count = job_count
            cijob.job_accuracy = job_accuracy

            db.session.add(cijob)
            db.session.commit()
            return 0, None
        except Exception as e:
            current_app.logger.error(str(e))
            return 102, str(e)

    @classmethod
    def delete(cls, id):
        try:
            ci_job = CiJob.query.get(id)
            if ci_job is None:
                return 0
            ci_job.status = CiJob.DISABLE
            db.session.add(ci_job)
            db.session.commit()
            return 0
        except Exception as e:
            current_app.logger.error(str(e))
            return 105, str(e)

    @classmethod
    def gain_jenkins_server(cls):

        jenkins_config = cls.public_trpc.requests('get', '/public/config', {'module': 'jenkins', 'module_type': 2})
        if not jenkins_config:
            return None
        run_dict = json.loads(jenkins_config)
        jenkins_server_url = run_dict['url']
        user_id = run_dict['user_id']
        api_token = run_dict['api_token']

        server = jenkins.Jenkins(jenkins_server_url, username=user_id, password=api_token)
        return server
